package com.etxxy.web.controller;

import java.io.IOException;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

import com.etxxy.common.ScanEventDTO;
import com.etxxy.common.cache.RedisTemplate;
import com.etxxy.common.exception.DataException;
import com.etxxy.common.exception.ServiceException;
import com.etxxy.common.json.JSON;
import com.etxxy.common.type.ScanEventEnum;
import com.etxxy.common.util.MD5Util;
import com.etxxy.common.util.QRCodeUtil;
import com.etxxy.common.util.RandomWordsUtil;
import com.etxxy.member.domain.Member;
import com.etxxy.member.service.MemberService;
import com.etxxy.web.constance.EnterpriseWebPropertis;

@RestController
public class IndexController extends BaseController {

	private static final Logger logger = LoggerFactory.getLogger(IndexController.class);
	@Autowired
	private MemberService memberService;
	@Autowired
	private EnterpriseWebPropertis enterpriseWebPropertis;

	@Autowired
	private RedisTemplate redisTemplate;

	/**
	 * @category 首页
	 * @return
	 */
	@RequestMapping()
	public ModelAndView indexRoot() {
		return new ModelAndView("index");
	}

	/**
	 * @category 首页
	 * @return
	 */
	@RequestMapping("index")
	public ModelAndView index() {
		return new ModelAndView("index");
	}

	/**
	 * @category 重定向至错误
	 * @param message
	 * @return
	 */
	@RequestMapping("error")
	public ModelAndView renderErrorMessage(String message) {
		ModelAndView mav = new ModelAndView("error");
		mav.addObject("errorMessages", message);
		return mav;
	}

	/**
	 * @category 去登陆
	 * @return
	 */
	@RequestMapping("login")
	public ModelAndView login() {
		return new ModelAndView("login");
	}

	/**
	 * @category 去注册
	 * @return
	 */
	@RequestMapping("register")
	public ModelAndView register() {
		return new ModelAndView("member/register");
	}

	@RequestMapping("doLogin")
	public String doLogin(String username, String password) {
		if (StringUtils.isBlank(username) || StringUtils.isBlank(password)) {
			return null;
		}
		password = MD5Util.md5(password);
		UsernamePasswordToken token = new UsernamePasswordToken(username, password);
		// 开始验证
		Subject subject = SecurityUtils.getSubject();
		try {
			subject.login(token);
		} catch (AuthenticationException e) {
			token.clear();
		}
		if (subject != null && subject.isAuthenticated()) {
			try {
				Member member = memberService.findMemberByMemberName(username);
				setSession(member);
			} catch (ServiceException e) {
				logger.error("会员服务失败e={}", e);
			} catch (DataException e) {
				logger.error("数据库失败e={}", e);
			}
		}
		Member me = getMemberFromSession();
		return JSON.toJSONString(me);
	}

	/**
	 * @category 退出
	 * @return
	 */
	@RequestMapping("loginOut")
	public String loginOut() {
		Subject subject = SecurityUtils.getSubject();
		subject.logout();
		return "";
	}

	/**
	 * @category 生成二维码
	 * @return
	 */
	@RequestMapping(value = "qrLogin", produces = { "application/json;charset=UTF-8" })
	@ResponseBody
	public String qrLogin() {
		Map<String, Object> resultMap = new HashMap<String, Object>();
		String enterpriseWebContentPath = enterpriseWebPropertis.getEnterpriseWebContentPath();
		String uuid = RandomWordsUtil.getRandom(12);
		logger.info("enterpriseWebContentPath={},uuid={}", enterpriseWebContentPath, uuid);
		String base64 = QRCodeUtil.toBase64(enterpriseWebContentPath + "/" + uuid, 300, 300);
		resultMap.put("uuid", uuid);
		resultMap.put("base64", base64);
		//设置到缓存中,用于判断二维码是否过期，在扫码和扫码后点击确认登陆的时候进行判断是否已经过期
		logger.info("resultMap={}", JSON.toJSONString(resultMap));
		ScanEventDTO scanEventDTO = new ScanEventDTO();
		scanEventDTO.setCode("0");
		scanEventDTO.setMsg("初始化二维码");
		scanEventDTO.setTimestamp(Calendar.getInstance().getTimeInMillis());
		redisTemplate.setex(ScanEventEnum.login.name() + ":" + uuid, 2 * 60, scanEventDTO);
		return JSON.toJSONString(resultMap);
	}

	/**
	 * @throws IOException 
	 * @category 生成二维码用于扫码登陆
	 */
	@RequestMapping(value = "waitQrLogin/{id}", produces = { "text/event-stream;charset=UTF-8" })
	@ResponseBody
	public String waitQrLogin(@PathVariable("id") String id, HttpServletResponse resp) throws IOException {
		ScanEventDTO scanEventDTO = redisTemplate.get(ScanEventEnum.login.name() + ":" + id);
		if (null != scanEventDTO) {
		} else {
			scanEventDTO = new ScanEventDTO();
			scanEventDTO.setCode("-1");
			scanEventDTO.setCode("二维码已过期，请重新刷新");
			scanEventDTO.setTimestamp(Calendar.getInstance().getTimeInMillis());
		}
		//返回json字符串
		return JSON.toJSONString(scanEventDTO);
	}

	/**
	 * @category 生成二维码用于扫码登陆
	 */
	@RequestMapping(value = "toQrLogin/{id}")
	public ModelAndView toQrLogin(@PathVariable("id") String id) {
		//跳转至确认登陆的页面 TODO
		ModelAndView mav = new ModelAndView();
		//App端扫描后的页面页面
		ScanEventDTO scanEventDTO = new ScanEventDTO();
		scanEventDTO.setCode("1");
		scanEventDTO.setMsg("天下信用App已扫描二维码");
		scanEventDTO.setTimestamp(Calendar.getInstance().getTimeInMillis());
		redisTemplate.setex(ScanEventEnum.login.name() + ":" + id, 2 * 60, scanEventDTO);
		return mav;
	}

	@RequestMapping(value = "doQrLogin/{id}/{mobile}")
	public String doQrLogin(@PathVariable("id") String id, @PathVariable("mobile") String mobile) {
		ScanEventDTO scanEventDTO = new ScanEventDTO();
		scanEventDTO.setCode("2");
		scanEventDTO.setMsg("天下信用App已确认登陆");
		scanEventDTO.setMobile(mobile);
		scanEventDTO.setTimestamp(Calendar.getInstance().getTimeInMillis());
		redisTemplate.setex(ScanEventEnum.login.name() + ":" + id, 2 * 60, scanEventDTO);

		// 需要增加一个心跳监测网页版是否在线 TODO
		return JSON.toJSONString(scanEventDTO);
	}

}
